using System;
using System.Collections.Generic;
using System.Net;
using System.Diagnostics;
using System.Text.RegularExpressions;

namespace TALoaders
{
    class GoogleDownloader : BaseLoader
    {
        #region Private members
        private System.Globalization.CultureInfo usCultureM = new System.Globalization.CultureInfo("en-US");
        private System.Globalization.CultureInfo gbCultureM = new System.Globalization.CultureInfo("en-GB");

        private string urlHistDataTmplM = "http://www.google.com/finance/historical?q=[ticker]" +
            "&startdate=[startMonth]+[startDay]%2C+[startYear]" +
            "&enddate=[endMonth]+[endDay]%2C+[endYear]" +
            "&output=csv";
        private string urlQuoteTmplM = "http://www.google.com/finance/info?client=ig&q=[ticker]";

        private WebClient webClientM = new WebClient();
        private TraceSwitch traceM = new TraceSwitch("GoogleLoader", "Debug messages in GoogleLoader");
        #endregion

        #region Public methods
        public GoogleDownloader()
            : base(Loader.Google)
        { }

        ~GoogleDownloader()
        {
            webClientM.Dispose();
        }

        override public SortedList<DateTime, Quote> getHistoricalPrices(string ticker, DateTime startDate, DateTime endDate)
        {
            // --->> prepare URL <<---
            // NOTE: Google's scheme requires Month as 3-char string: Jan, Feb, ...
            string startMonth = startDate.ToString("MMM");
            string startDay = startDate.Day.ToString();
            string startYear = startDate.Year.ToString();
            string endMonth = endDate.ToString("MMM");
            string endDay = endDate.Day.ToString();
            string endYear = endDate.Year.ToString();

            string url = urlHistDataTmplM.Replace("[ticker]", ticker);
            url = url.Replace("[startMonth]", startMonth);
            url = url.Replace("[startDay]", startDay);
            url = url.Replace("[startYear]", startYear);
            url = url.Replace("[endMonth]", endMonth);
            url = url.Replace("[endDay]", endDay);
            url = url.Replace("[endYear]", endYear);

            // --->> Download Data <<---
            Debug.WriteLineIf(traceM.TraceInfo, url);
            string history = webClientM.DownloadString(url); 

            // --->> Parse table <<---
            history = history.Replace("\r", "");        // trim off unused characters from end of line
            string[] rows = history.Split('\n');        // split to array on end of line
            string[] colNames = rows[0].Split(',');     // split column names: 0.Date, 1.Open, 2.High, 3.Low, 4.Close, 5.Volume

            int nOfRows = rows.Length - 2;  // 2 rows unused (the first with names andthe last which is empty)
            SortedList<DateTime, Quote> result = new SortedList<DateTime, Quote>(nOfRows);
            string[] rowData;

            for (int i = 0; i < nOfRows; ++i)
            {
                rowData = rows[nOfRows - i].Split(',');   // rows are in reverse order in Yahoo
                // 0:Date, 1:Open, 2:High, 3:Low, 4:Close, 5:Volume
                DateTime date = Convert.ToDateTime(rowData[0], gbCultureM);
                double open = Convert.ToDouble(rowData[1], usCultureM); ;
                double high = Convert.ToDouble(rowData[2], usCultureM);
                double low = Convert.ToDouble(rowData[3], usCultureM);
                double close = Convert.ToDouble(rowData[4], usCultureM);
                double volume = Convert.ToDouble(rowData[5], usCultureM);
                double adjClose = close;    // Close is already adjusted at Google
                Quote quote = new Quote(open, high, low, close, volume, adjClose);

                result.Add(date, quote);
            }
            return result;
        }
        override public double getLastPrice(string ticker, out string timeStamp)
        {
            timeStamp = null;
            string url = urlQuoteTmplM.Replace("[ticker]", ticker);

            // example: // [ { "id": "22144" ,"t" : "AAPL" ,"e" : "NASDAQ" ,"l" : "267.49" ,"l_cur" : "267.49" ,"ltt":"2:59PM EDT" ,"lt" : "Jun 16, 2:59PM EDT" ,"c" : "+7.80" ,"cp" : "3.00" ,"ccol" : "chg" } ]
            string sLastTrade = webClientM.DownloadString(url);
 
            sLastTrade = sLastTrade.Replace("\n","").Replace(" ",""); // remove all end-of-lines and empty-spaces

            int sIx = sLastTrade.IndexOf('{');  // get only part ofthe string inside brackets
            int eIx = sLastTrade.LastIndexOf('}');
            sLastTrade = sLastTrade.Substring(sIx+1, eIx-sIx-2);

            string[] tagValue = Regex.Split(sLastTrade, "\",\"");
            
            double result = 0;
            foreach(string tv in tagValue)
            {
                string[] row = Regex.Split(tv, "\":\"");
                if (row.Length == 2 && row[0] == "l") // l=LastTrade, t=Ticker, id=ID, lt=TradeDate
                    result = Convert.ToDouble(row[1], usCultureM);
                else if (row.Length == 2 && row[0] == "lt")
                    timeStamp = row[1];
            }
            return result;
        }
        #endregion
    }
}
